package com.jiuling.qiniu.oss;

import com.jiuling.qiniu.oss.config.QiNiuOssConfig;
import com.jiuling.qiniu.oss.model.FileInfoModel;
import com.jiuling.qiniu.oss.model.enums.FileRestoreStatusEnum;
import com.jiuling.qiniu.oss.model.enums.FileStatusEnum;
import com.jiuling.qiniu.oss.model.enums.FileTypeEnum;
import com.qiniu.common.QiniuException;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import org.jiuling.local.tools.exception.LocalToolsException;
import org.jiuling.local.tools.util.EnumUtil;
import org.jiuling.local.tools.verify.ArrayVerify;
import org.jiuling.local.tools.verify.Assertions;
import org.jiuling.local.tools.verify.IntegerVerify;
import org.jiuling.local.tools.verify.ObjectVerify;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 资源管理
 * @author 紫灵
 * @date 2023年05月23日 10时41分22秒
 */
public class ResourceManagement {

    private final QiNiuOssConfig qiNiuOssConfig;
    private final BucketManager bucketManager;
    public ResourceManagement(QiNiuOssConfig qiNiuOssConfig) {
        this.qiNiuOssConfig = qiNiuOssConfig;
        this.bucketManager = new BucketManager(
                Auth.create(qiNiuOssConfig.getQiNiuConfig().getAccessKey(), qiNiuOssConfig.getQiNiuConfig().getSecretKey()),
                //构造一个带指定 Region 对象的配置类
                new Configuration(qiNiuOssConfig.getRegion())
        );
    }

    /**
     * 获取文件信息
     * @param fileKey 文件key
     * @return 文件信息模型
     */
    public FileInfoModel getFileInfo(String fileKey){
        FileInfoModel fileInfoModel = null;
        try {
            fileInfoModel =  fileInfoToFileInfoModel(bucketManager.stat(qiNiuOssConfig.getBucket(), fileKey));
        } catch (QiniuException e) {
            e.printStackTrace();
        }
        return fileInfoModel;
    }

    /**
     * 获取空间文件列表
     * @param prefix 文件前缀
     * @param delimiter 目录分隔符
     * @return 文件模型列表
     */
    public List<FileInfoModel> getSpatialFileList(String prefix,String delimiter,Integer limit){
        if(IntegerVerify.isBlank(limit)){
            limit = 1000;
        }
        Assertions.isNotTrue("文件迭代最大长度不能超过1000",limit > 1000);
        //列举空间文件列表
        BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(qiNiuOssConfig.getBucket(), prefix, limit, delimiter);
        List<FileInfoModel> fileInfoModelList = null;
        while (fileListIterator.hasNext()) {
            //处理获取的file list结果
            FileInfo[] items = fileListIterator.next();
            if(!ArrayVerify.isEmpty(items)){
                fileInfoModelList = Arrays.stream(items).map(this::fileInfoToFileInfoModel).collect(Collectors.toList());
            }
        }
        return fileInfoModelList;
    }

    public void deleteSpatialFile(String fileKye){
        try {
            bucketManager.delete(qiNiuOssConfig.getBucket(), fileKye);
        } catch (QiniuException e) {
            e.printStackTrace();
//            //如果遇到异常，说明删除失败
//            System.err.println(ex.code());
//            System.err.println(ex.response.toString());
        }
    }

    /**
     * 文件信息转换为文件信息模型
     * @param fileInfo 文件信息
     * @return 文件信息模型
     */
    private FileInfoModel fileInfoToFileInfoModel(FileInfo fileInfo){
        if(ObjectVerify.isNull(fileInfo)){
            return null;
        }
        FileInfoModel fileInfoModel = new FileInfoModel();
        fileInfoModel.setKey(fileInfo.key);
        fileInfoModel.setHash(fileInfo.hash);
        fileInfoModel.setFsize(fileInfo.fsize);
        fileInfoModel.setPutTime(fileInfo.putTime);
        fileInfoModel.setMimeType(fileInfo.mimeType);
        fileInfoModel.setEndUser(fileInfo.endUser);
        fileInfoModel.setMd5(fileInfo.md5);
        fileInfoModel.setExpiration(fileInfo.expiration);
        fileInfoModel.setTransitionToIA(fileInfo.transitionToIA);
        fileInfoModel.setTransitionToArchive(fileInfo.transitionToArchive);
        fileInfoModel.setTransitionToDeepArchive(fileInfo.transitionToDeepArchive);
        fileInfoModel.setMeta(fileInfo.meta);
        try {
            Integer restoreStatus = fileInfo.restoreStatus;

            if(!IntegerVerify.isBlank(restoreStatus)){
                fileInfoModel.setRestoreStatus(EnumUtil.valueOfEnum(FileRestoreStatusEnum.class,restoreStatus,"getCode"));
            }
            fileInfoModel.setType(EnumUtil.valueOfEnum(FileTypeEnum.class,fileInfo.type,"getCode"));
            fileInfoModel.setStatus(EnumUtil.valueOfEnum(FileStatusEnum.class,fileInfo.status,"getCode"));
        } catch (LocalToolsException e) {
            throw new RuntimeException(e);
        }
        return fileInfoModel;
    }

}
